package elijah.base.thread;


import com.jeremyliao.liveeventbus.LiveEventBus;

import org.reactivestreams.Publisher;

import io.reactivex.Completable;
import io.reactivex.CompletableSource;
import io.reactivex.CompletableTransformer;
import io.reactivex.Flowable;
import io.reactivex.FlowableTransformer;
import io.reactivex.Maybe;
import io.reactivex.MaybeSource;
import io.reactivex.MaybeTransformer;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.SingleTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class Threads {
    public static void updateFlexRate(String tag, long time) {
        LiveEventBus.get(ScheduledProvider.FLEX_RATE + tag).post(time);
    }

    public static <T> IO2Main<T> io2main() {
        return new IO2Main<>();
    }

    public static <T> IO2NewThread<T> io2newThread() {
        return new IO2NewThread<>();
    }

    static class IO2Main<T> implements ObservableTransformer<T, T>, CompletableTransformer, SingleTransformer<T, T>, MaybeTransformer<T, T>, FlowableTransformer<T, T> {

        @Override
        public ObservableSource<T> apply(Observable<T> upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
        }

        @Override
        public CompletableSource apply(Completable upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
        }

        @Override
        public SingleSource<T> apply(Single<T> upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
        }

        @Override
        public Publisher<T> apply(Flowable<T> upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
        }

        @Override
        public MaybeSource<T> apply(Maybe<T> upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
        }
    }

    static class IO2NewThread<T> implements ObservableTransformer<T, T>, CompletableTransformer, SingleTransformer<T, T>, MaybeTransformer<T, T>, FlowableTransformer<T, T> {

        @Override
        public ObservableSource<T> apply(Observable<T> upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(Schedulers.newThread());
        }

        @Override
        public CompletableSource apply(Completable upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(Schedulers.newThread());
        }

        @Override
        public SingleSource<T> apply(Single<T> upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(Schedulers.newThread());
        }

        @Override
        public Publisher<T> apply(Flowable<T> upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(Schedulers.newThread());
        }

        @Override
        public MaybeSource<T> apply(Maybe<T> upstream) {
            return upstream.unsubscribeOn(Schedulers.newThread()).subscribeOn(Schedulers.io()).observeOn(Schedulers.newThread());
        }
    }
}
